//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension IoTDeviceAdvisor {
    // MARK: Enums

    public enum Status: String, CustomStringConvertible, Codable, _SotoSendable {
        case canceled = "CANCELED"
        case error = "ERROR"
        case fail = "FAIL"
        case pass = "PASS"
        case passWithWarnings = "PASS_WITH_WARNINGS"
        case pending = "PENDING"
        case running = "RUNNING"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        public var description: String { return self.rawValue }
    }

    public enum SuiteRunStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case canceled = "CANCELED"
        case error = "ERROR"
        case fail = "FAIL"
        case pass = "PASS"
        case passWithWarnings = "PASS_WITH_WARNINGS"
        case pending = "PENDING"
        case running = "RUNNING"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        public var description: String { return self.rawValue }
    }

    public enum TestCaseScenarioStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case canceled = "CANCELED"
        case error = "ERROR"
        case fail = "FAIL"
        case pass = "PASS"
        case passWithWarnings = "PASS_WITH_WARNINGS"
        case pending = "PENDING"
        case running = "RUNNING"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        public var description: String { return self.rawValue }
    }

    public enum TestCaseScenarioType: String, CustomStringConvertible, Codable, _SotoSendable {
        case advanced = "Advanced"
        case basic = "Basic"
        public var description: String { return self.rawValue }
    }

    public enum `Protocol`: String, CustomStringConvertible, Codable, _SotoSendable {
        case mqttV311 = "MqttV3_1_1"
        case mqttV5 = "MqttV5"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct CreateSuiteDefinitionRequest: AWSEncodableShape {
        /// Creates a Device Advisor test suite with suite definition configuration.
        public let suiteDefinitionConfiguration: SuiteDefinitionConfiguration
        /// The tags to be attached to the suite definition.
        public let tags: [String: String]?

        public init(suiteDefinitionConfiguration: SuiteDefinitionConfiguration, tags: [String: String]? = nil) {
            self.suiteDefinitionConfiguration = suiteDefinitionConfiguration
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.suiteDefinitionConfiguration.validate(name: "\(name).suiteDefinitionConfiguration")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case suiteDefinitionConfiguration
            case tags
        }
    }

    public struct CreateSuiteDefinitionResponse: AWSDecodableShape {
        /// The timestamp of when the test suite was created.
        public let createdAt: Date?
        /// The Amazon Resource Name (ARN) of the test suite.
        public let suiteDefinitionArn: String?
        /// The UUID of the test suite created.
        public let suiteDefinitionId: String?
        /// The suite definition name of the test suite. This is a required parameter.
        public let suiteDefinitionName: String?

        public init(createdAt: Date? = nil, suiteDefinitionArn: String? = nil, suiteDefinitionId: String? = nil, suiteDefinitionName: String? = nil) {
            self.createdAt = createdAt
            self.suiteDefinitionArn = suiteDefinitionArn
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteDefinitionName = suiteDefinitionName
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case suiteDefinitionArn
            case suiteDefinitionId
            case suiteDefinitionName
        }
    }

    public struct DeleteSuiteDefinitionRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "suiteDefinitionId", location: .uri("suiteDefinitionId"))
        ]

        /// Suite definition ID of the test suite to be deleted.
        public let suiteDefinitionId: String

        public init(suiteDefinitionId: String) {
            self.suiteDefinitionId = suiteDefinitionId
        }

        public func validate(name: String) throws {
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, max: 36)
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, min: 12)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteSuiteDefinitionResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeviceUnderTest: AWSEncodableShape & AWSDecodableShape {
        /// Lists devices certificate ARN.
        public let certificateArn: String?
        /// Lists devices thing ARN.
        public let thingArn: String?

        public init(certificateArn: String? = nil, thingArn: String? = nil) {
            self.certificateArn = certificateArn
            self.thingArn = thingArn
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.thingArn, name: "thingArn", parent: name, max: 2048)
            try self.validate(self.thingArn, name: "thingArn", parent: name, min: 20)
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn
            case thingArn
        }
    }

    public struct GetEndpointRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "certificateArn", location: .querystring("certificateArn")),
            AWSMemberEncoding(label: "thingArn", location: .querystring("thingArn"))
        ]

        /// The certificate ARN of the device. This is an optional parameter.
        public let certificateArn: String?
        /// The thing ARN of the device. This is an optional parameter.
        public let thingArn: String?

        public init(certificateArn: String? = nil, thingArn: String? = nil) {
            self.certificateArn = certificateArn
            self.thingArn = thingArn
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 20)
            try self.validate(self.thingArn, name: "thingArn", parent: name, max: 2048)
            try self.validate(self.thingArn, name: "thingArn", parent: name, min: 20)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetEndpointResponse: AWSDecodableShape {
        /// The response of an Device Advisor endpoint.
        public let endpoint: String?

        public init(endpoint: String? = nil) {
            self.endpoint = endpoint
        }

        private enum CodingKeys: String, CodingKey {
            case endpoint
        }
    }

    public struct GetSuiteDefinitionRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "suiteDefinitionId", location: .uri("suiteDefinitionId")),
            AWSMemberEncoding(label: "suiteDefinitionVersion", location: .querystring("suiteDefinitionVersion"))
        ]

        /// Suite definition ID of the test suite to get.
        public let suiteDefinitionId: String
        /// Suite definition version of the test suite to get.
        public let suiteDefinitionVersion: String?

        public init(suiteDefinitionId: String, suiteDefinitionVersion: String? = nil) {
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteDefinitionVersion = suiteDefinitionVersion
        }

        public func validate(name: String) throws {
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, max: 36)
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, min: 12)
            try self.validate(self.suiteDefinitionVersion, name: "suiteDefinitionVersion", parent: name, max: 255)
            try self.validate(self.suiteDefinitionVersion, name: "suiteDefinitionVersion", parent: name, min: 2)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetSuiteDefinitionResponse: AWSDecodableShape {
        /// Date (in Unix epoch time) when the suite definition was created.
        public let createdAt: Date?
        /// Date (in Unix epoch time) when the suite definition was last modified.
        public let lastModifiedAt: Date?
        /// Latest suite definition version of the suite definition.
        public let latestVersion: String?
        /// The ARN of the suite definition.
        public let suiteDefinitionArn: String?
        /// Suite configuration of the suite definition.
        public let suiteDefinitionConfiguration: SuiteDefinitionConfiguration?
        /// Suite definition ID of the suite definition.
        public let suiteDefinitionId: String?
        /// Suite definition version of the suite definition.
        public let suiteDefinitionVersion: String?
        /// Tags attached to the suite definition.
        public let tags: [String: String]?

        public init(createdAt: Date? = nil, lastModifiedAt: Date? = nil, latestVersion: String? = nil, suiteDefinitionArn: String? = nil, suiteDefinitionConfiguration: SuiteDefinitionConfiguration? = nil, suiteDefinitionId: String? = nil, suiteDefinitionVersion: String? = nil, tags: [String: String]? = nil) {
            self.createdAt = createdAt
            self.lastModifiedAt = lastModifiedAt
            self.latestVersion = latestVersion
            self.suiteDefinitionArn = suiteDefinitionArn
            self.suiteDefinitionConfiguration = suiteDefinitionConfiguration
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteDefinitionVersion = suiteDefinitionVersion
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case lastModifiedAt
            case latestVersion
            case suiteDefinitionArn
            case suiteDefinitionConfiguration
            case suiteDefinitionId
            case suiteDefinitionVersion
            case tags
        }
    }

    public struct GetSuiteRunReportRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "suiteDefinitionId", location: .uri("suiteDefinitionId")),
            AWSMemberEncoding(label: "suiteRunId", location: .uri("suiteRunId"))
        ]

        /// Suite definition ID of the test suite.
        public let suiteDefinitionId: String
        /// Suite run ID of the test suite run.
        public let suiteRunId: String

        public init(suiteDefinitionId: String, suiteRunId: String) {
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteRunId = suiteRunId
        }

        public func validate(name: String) throws {
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, max: 36)
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, min: 12)
            try self.validate(self.suiteRunId, name: "suiteRunId", parent: name, max: 36)
            try self.validate(self.suiteRunId, name: "suiteRunId", parent: name, min: 12)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetSuiteRunReportResponse: AWSDecodableShape {
        /// Download URL of the qualification report.
        public let qualificationReportDownloadUrl: String?

        public init(qualificationReportDownloadUrl: String? = nil) {
            self.qualificationReportDownloadUrl = qualificationReportDownloadUrl
        }

        private enum CodingKeys: String, CodingKey {
            case qualificationReportDownloadUrl
        }
    }

    public struct GetSuiteRunRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "suiteDefinitionId", location: .uri("suiteDefinitionId")),
            AWSMemberEncoding(label: "suiteRunId", location: .uri("suiteRunId"))
        ]

        /// Suite definition ID for the test suite run.
        public let suiteDefinitionId: String
        /// Suite run ID for the test suite run.
        public let suiteRunId: String

        public init(suiteDefinitionId: String, suiteRunId: String) {
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteRunId = suiteRunId
        }

        public func validate(name: String) throws {
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, max: 36)
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, min: 12)
            try self.validate(self.suiteRunId, name: "suiteRunId", parent: name, max: 36)
            try self.validate(self.suiteRunId, name: "suiteRunId", parent: name, min: 12)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetSuiteRunResponse: AWSDecodableShape {
        /// Date (in Unix epoch time) when the test suite run ended.
        public let endTime: Date?
        /// Error reason for any test suite run failure.
        public let errorReason: String?
        /// Date (in Unix epoch time) when the test suite run started.
        public let startTime: Date?
        /// Status for the test suite run.
        public let status: SuiteRunStatus?
        /// Suite definition ID for the test suite run.
        public let suiteDefinitionId: String?
        /// Suite definition version for the test suite run.
        public let suiteDefinitionVersion: String?
        /// The ARN of the suite run.
        public let suiteRunArn: String?
        /// Suite run configuration for the test suite run.
        public let suiteRunConfiguration: SuiteRunConfiguration?
        /// Suite run ID for the test suite run.
        public let suiteRunId: String?
        /// The tags attached to the suite run.
        public let tags: [String: String]?
        /// Test results for the test suite run.
        public let testResult: TestResult?

        public init(endTime: Date? = nil, errorReason: String? = nil, startTime: Date? = nil, status: SuiteRunStatus? = nil, suiteDefinitionId: String? = nil, suiteDefinitionVersion: String? = nil, suiteRunArn: String? = nil, suiteRunConfiguration: SuiteRunConfiguration? = nil, suiteRunId: String? = nil, tags: [String: String]? = nil, testResult: TestResult? = nil) {
            self.endTime = endTime
            self.errorReason = errorReason
            self.startTime = startTime
            self.status = status
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteDefinitionVersion = suiteDefinitionVersion
            self.suiteRunArn = suiteRunArn
            self.suiteRunConfiguration = suiteRunConfiguration
            self.suiteRunId = suiteRunId
            self.tags = tags
            self.testResult = testResult
        }

        private enum CodingKeys: String, CodingKey {
            case endTime
            case errorReason
            case startTime
            case status
            case suiteDefinitionId
            case suiteDefinitionVersion
            case suiteRunArn
            case suiteRunConfiguration
            case suiteRunId
            case tags
            case testResult
        }
    }

    public struct GroupResult: AWSDecodableShape {
        /// Group result ID.
        public let groupId: String?
        /// Group Result Name.
        public let groupName: String?
        /// Tests under Group Result.
        public let tests: [TestCaseRun]?

        public init(groupId: String? = nil, groupName: String? = nil, tests: [TestCaseRun]? = nil) {
            self.groupId = groupId
            self.groupName = groupName
            self.tests = tests
        }

        private enum CodingKeys: String, CodingKey {
            case groupId
            case groupName
            case tests
        }
    }

    public struct ListSuiteDefinitionsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken"))
        ]

        /// The maximum number of results to return at once.
        public let maxResults: Int?
        /// A token used to get the next set of results.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2000)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListSuiteDefinitionsResponse: AWSDecodableShape {
        /// A token used to get the next set of results.
        public let nextToken: String?
        /// An array of objects that provide summaries of information about the suite definitions in the list.
        public let suiteDefinitionInformationList: [SuiteDefinitionInformation]?

        public init(nextToken: String? = nil, suiteDefinitionInformationList: [SuiteDefinitionInformation]? = nil) {
            self.nextToken = nextToken
            self.suiteDefinitionInformationList = suiteDefinitionInformationList
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case suiteDefinitionInformationList
        }
    }

    public struct ListSuiteRunsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken")),
            AWSMemberEncoding(label: "suiteDefinitionId", location: .querystring("suiteDefinitionId")),
            AWSMemberEncoding(label: "suiteDefinitionVersion", location: .querystring("suiteDefinitionVersion"))
        ]

        /// The maximum number of results to return at once.
        public let maxResults: Int?
        /// A token to retrieve the next set of results.
        public let nextToken: String?
        /// Lists the test suite runs of the specified test suite based on suite definition ID.
        public let suiteDefinitionId: String?
        /// Must be passed along with suiteDefinitionId. Lists the test suite runs of the specified test suite based on suite definition version.
        public let suiteDefinitionVersion: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil, suiteDefinitionId: String? = nil, suiteDefinitionVersion: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteDefinitionVersion = suiteDefinitionVersion
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2000)
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, max: 36)
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, min: 12)
            try self.validate(self.suiteDefinitionVersion, name: "suiteDefinitionVersion", parent: name, max: 255)
            try self.validate(self.suiteDefinitionVersion, name: "suiteDefinitionVersion", parent: name, min: 2)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListSuiteRunsResponse: AWSDecodableShape {
        /// A token to retrieve the next set of results.
        public let nextToken: String?
        /// An array of objects that provide summaries of information about the suite runs in the list.
        public let suiteRunsList: [SuiteRunInformation]?

        public init(nextToken: String? = nil, suiteRunsList: [SuiteRunInformation]? = nil) {
            self.nextToken = nextToken
            self.suiteRunsList = suiteRunsList
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case suiteRunsList
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        /// The resource ARN of the IoT Device Advisor resource. This can be SuiteDefinition ARN or SuiteRun ARN.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 20)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The tags attached to the IoT Device Advisor resource.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct StartSuiteRunRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "suiteDefinitionId", location: .uri("suiteDefinitionId"))
        ]

        /// Suite definition ID of the test suite.
        public let suiteDefinitionId: String
        /// Suite definition version of the test suite.
        public let suiteDefinitionVersion: String?
        /// Suite run configuration.
        public let suiteRunConfiguration: SuiteRunConfiguration
        /// The tags to be attached to the suite run.
        public let tags: [String: String]?

        public init(suiteDefinitionId: String, suiteDefinitionVersion: String? = nil, suiteRunConfiguration: SuiteRunConfiguration, tags: [String: String]? = nil) {
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteDefinitionVersion = suiteDefinitionVersion
            self.suiteRunConfiguration = suiteRunConfiguration
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, max: 36)
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, min: 12)
            try self.validate(self.suiteDefinitionVersion, name: "suiteDefinitionVersion", parent: name, max: 255)
            try self.validate(self.suiteDefinitionVersion, name: "suiteDefinitionVersion", parent: name, min: 2)
            try self.suiteRunConfiguration.validate(name: "\(name).suiteRunConfiguration")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case suiteDefinitionVersion
            case suiteRunConfiguration
            case tags
        }
    }

    public struct StartSuiteRunResponse: AWSDecodableShape {
        /// Starts a Device Advisor test suite run based on suite create time.
        public let createdAt: Date?
        /// The response of an Device Advisor test endpoint.
        public let endpoint: String?
        /// Amazon Resource Name (ARN) of the started suite run.
        public let suiteRunArn: String?
        /// Suite Run ID of the started suite run.
        public let suiteRunId: String?

        public init(createdAt: Date? = nil, endpoint: String? = nil, suiteRunArn: String? = nil, suiteRunId: String? = nil) {
            self.createdAt = createdAt
            self.endpoint = endpoint
            self.suiteRunArn = suiteRunArn
            self.suiteRunId = suiteRunId
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case endpoint
            case suiteRunArn
            case suiteRunId
        }
    }

    public struct StopSuiteRunRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "suiteDefinitionId", location: .uri("suiteDefinitionId")),
            AWSMemberEncoding(label: "suiteRunId", location: .uri("suiteRunId"))
        ]

        /// Suite definition ID of the test suite run to be stopped.
        public let suiteDefinitionId: String
        /// Suite run ID of the test suite run to be stopped.
        public let suiteRunId: String

        public init(suiteDefinitionId: String, suiteRunId: String) {
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteRunId = suiteRunId
        }

        public func validate(name: String) throws {
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, max: 36)
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, min: 12)
            try self.validate(self.suiteRunId, name: "suiteRunId", parent: name, max: 36)
            try self.validate(self.suiteRunId, name: "suiteRunId", parent: name, min: 12)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct StopSuiteRunResponse: AWSDecodableShape {
        public init() {}
    }

    public struct SuiteDefinitionConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Gets the device permission ARN. This is a required parameter.
        public let devicePermissionRoleArn: String
        /// Gets the devices configured.
        public let devices: [DeviceUnderTest]?
        /// Gets the tests intended for qualification in a suite.
        public let intendedForQualification: Bool?
        /// Verifies if the test suite is a long duration test.
        public let isLongDurationTest: Bool?
        /// Sets the MQTT protocol that is configured in the suite definition.
        public let `protocol`: `Protocol`?
        /// Gets the test suite root group. This is a required parameter.
        public let rootGroup: String
        /// Gets the suite definition name. This is a required parameter.
        public let suiteDefinitionName: String

        public init(devicePermissionRoleArn: String, devices: [DeviceUnderTest]? = nil, intendedForQualification: Bool? = nil, isLongDurationTest: Bool? = nil, protocol: `Protocol`? = nil, rootGroup: String, suiteDefinitionName: String) {
            self.devicePermissionRoleArn = devicePermissionRoleArn
            self.devices = devices
            self.intendedForQualification = intendedForQualification
            self.isLongDurationTest = isLongDurationTest
            self.`protocol` = `protocol`
            self.rootGroup = rootGroup
            self.suiteDefinitionName = suiteDefinitionName
        }

        public func validate(name: String) throws {
            try self.validate(self.devicePermissionRoleArn, name: "devicePermissionRoleArn", parent: name, max: 2048)
            try self.validate(self.devicePermissionRoleArn, name: "devicePermissionRoleArn", parent: name, min: 20)
            try self.devices?.forEach {
                try $0.validate(name: "\(name).devices[]")
            }
            try self.validate(self.devices, name: "devices", parent: name, max: 2)
            try self.validate(self.rootGroup, name: "rootGroup", parent: name, max: 2048)
            try self.validate(self.rootGroup, name: "rootGroup", parent: name, min: 1)
            try self.validate(self.suiteDefinitionName, name: "suiteDefinitionName", parent: name, max: 256)
            try self.validate(self.suiteDefinitionName, name: "suiteDefinitionName", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case devicePermissionRoleArn
            case devices
            case intendedForQualification
            case isLongDurationTest
            case `protocol`
            case rootGroup
            case suiteDefinitionName
        }
    }

    public struct SuiteDefinitionInformation: AWSDecodableShape {
        /// Date (in Unix epoch time) when the test suite was created.
        public let createdAt: Date?
        /// Specifies the devices that are under test for the test suite.
        public let defaultDevices: [DeviceUnderTest]?
        /// Specifies if the test suite is intended for qualification.
        public let intendedForQualification: Bool?
        /// Verifies if the test suite is a long duration test.
        public let isLongDurationTest: Bool?
        /// Gets the MQTT protocol that is configured in the suite definition.
        public let `protocol`: `Protocol`?
        /// Suite definition ID of the test suite.
        public let suiteDefinitionId: String?
        /// Suite name of the test suite.
        public let suiteDefinitionName: String?

        public init(createdAt: Date? = nil, defaultDevices: [DeviceUnderTest]? = nil, intendedForQualification: Bool? = nil, isLongDurationTest: Bool? = nil, protocol: `Protocol`? = nil, suiteDefinitionId: String? = nil, suiteDefinitionName: String? = nil) {
            self.createdAt = createdAt
            self.defaultDevices = defaultDevices
            self.intendedForQualification = intendedForQualification
            self.isLongDurationTest = isLongDurationTest
            self.`protocol` = `protocol`
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteDefinitionName = suiteDefinitionName
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case defaultDevices
            case intendedForQualification
            case isLongDurationTest
            case `protocol`
            case suiteDefinitionId
            case suiteDefinitionName
        }
    }

    public struct SuiteRunConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// TRUE if multiple test suites run in parallel.
        public let parallelRun: Bool?
        /// Sets the primary device for the test suite run. This requires a thing ARN or a certificate ARN.
        public let primaryDevice: DeviceUnderTest
        /// Sets test case list.
        public let selectedTestList: [String]?

        public init(parallelRun: Bool? = nil, primaryDevice: DeviceUnderTest, selectedTestList: [String]? = nil) {
            self.parallelRun = parallelRun
            self.primaryDevice = primaryDevice
            self.selectedTestList = selectedTestList
        }

        public func validate(name: String) throws {
            try self.primaryDevice.validate(name: "\(name).primaryDevice")
            try self.selectedTestList?.forEach {
                try validate($0, name: "selectedTestList[]", parent: name, max: 36)
                try validate($0, name: "selectedTestList[]", parent: name, min: 12)
            }
            try self.validate(self.selectedTestList, name: "selectedTestList", parent: name, max: 100)
        }

        private enum CodingKeys: String, CodingKey {
            case parallelRun
            case primaryDevice
            case selectedTestList
        }
    }

    public struct SuiteRunInformation: AWSDecodableShape {
        /// Date (in Unix epoch time) when the suite run was created.
        public let createdAt: Date?
        /// Date (in Unix epoch time) when the suite run ended.
        public let endAt: Date?
        /// Number of test cases that failed in the suite run.
        public let failed: Int?
        /// Number of test cases that passed in the suite run.
        public let passed: Int?
        /// Date (in Unix epoch time) when the suite run was started.
        public let startedAt: Date?
        /// Status of the suite run.
        public let status: SuiteRunStatus?
        /// Suite definition ID of the suite run.
        public let suiteDefinitionId: String?
        /// Suite definition name of the suite run.
        public let suiteDefinitionName: String?
        /// Suite definition version of the suite run.
        public let suiteDefinitionVersion: String?
        /// Suite run ID of the suite run.
        public let suiteRunId: String?

        public init(createdAt: Date? = nil, endAt: Date? = nil, failed: Int? = nil, passed: Int? = nil, startedAt: Date? = nil, status: SuiteRunStatus? = nil, suiteDefinitionId: String? = nil, suiteDefinitionName: String? = nil, suiteDefinitionVersion: String? = nil, suiteRunId: String? = nil) {
            self.createdAt = createdAt
            self.endAt = endAt
            self.failed = failed
            self.passed = passed
            self.startedAt = startedAt
            self.status = status
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteDefinitionName = suiteDefinitionName
            self.suiteDefinitionVersion = suiteDefinitionVersion
            self.suiteRunId = suiteRunId
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case endAt
            case failed
            case passed
            case startedAt
            case status
            case suiteDefinitionId
            case suiteDefinitionName
            case suiteDefinitionVersion
            case suiteRunId
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        /// The resource ARN of an IoT Device Advisor resource.  This can be SuiteDefinition ARN or SuiteRun ARN.
        public let resourceArn: String
        /// The tags to be attached to the IoT Device Advisor resource.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 20)
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct TestCaseRun: AWSDecodableShape {
        /// Provides test case run end time.
        public let endTime: Date?
        /// Provides test case run failure result.
        public let failure: String?
        /// Provides test case run log URL.
        public let logUrl: String?
        /// Provides test case run start time.
        public let startTime: Date?
        /// Provides the test case run status. Status is one of the following:    PASS: Test passed.    FAIL: Test failed.    PENDING: Test has not started running but is scheduled.    RUNNING: Test is running.    STOPPING: Test is performing cleanup steps. You will see this status only if you stop a suite run.    STOPPED Test is stopped. You will see this status only if you stop a suite run.    PASS_WITH_WARNINGS: Test passed with warnings.    ERORR: Test faced an error when running due to an internal issue.
        public let status: Status?
        /// Provides the test case run definition ID.
        public let testCaseDefinitionId: String?
        /// Provides the test case run definition name.
        public let testCaseDefinitionName: String?
        /// Provides the test case run ID.
        public let testCaseRunId: String?
        ///  Provides the test scenarios for the test case run.
        public let testScenarios: [TestCaseScenario]?
        /// Provides test case run warnings.
        public let warnings: String?

        public init(endTime: Date? = nil, failure: String? = nil, logUrl: String? = nil, startTime: Date? = nil, status: Status? = nil, testCaseDefinitionId: String? = nil, testCaseDefinitionName: String? = nil, testCaseRunId: String? = nil, testScenarios: [TestCaseScenario]? = nil, warnings: String? = nil) {
            self.endTime = endTime
            self.failure = failure
            self.logUrl = logUrl
            self.startTime = startTime
            self.status = status
            self.testCaseDefinitionId = testCaseDefinitionId
            self.testCaseDefinitionName = testCaseDefinitionName
            self.testCaseRunId = testCaseRunId
            self.testScenarios = testScenarios
            self.warnings = warnings
        }

        private enum CodingKeys: String, CodingKey {
            case endTime
            case failure
            case logUrl
            case startTime
            case status
            case testCaseDefinitionId
            case testCaseDefinitionName
            case testCaseRunId
            case testScenarios
            case warnings
        }
    }

    public struct TestCaseScenario: AWSDecodableShape {
        /// Provides test case scenario failure result.
        public let failure: String?
        /// Provides the test case scenario status. Status is one of the following:    PASS: Test passed.    FAIL: Test failed.    PENDING: Test has not started running but is scheduled.    RUNNING: Test is running.    STOPPING: Test is performing cleanup steps. You will see this status only if you stop a suite run.    STOPPED Test is stopped. You will see this status only if you stop a suite run.    PASS_WITH_WARNINGS: Test passed with warnings.    ERORR: Test faced an error when running due to an internal issue.
        public let status: TestCaseScenarioStatus?
        ///
        public let systemMessage: String?
        /// Provides test case scenario ID.
        public let testCaseScenarioId: String?
        /// Provides test case scenario type. Type is one of the following:   Advanced   Basic
        public let testCaseScenarioType: TestCaseScenarioType?

        public init(failure: String? = nil, status: TestCaseScenarioStatus? = nil, systemMessage: String? = nil, testCaseScenarioId: String? = nil, testCaseScenarioType: TestCaseScenarioType? = nil) {
            self.failure = failure
            self.status = status
            self.systemMessage = systemMessage
            self.testCaseScenarioId = testCaseScenarioId
            self.testCaseScenarioType = testCaseScenarioType
        }

        private enum CodingKeys: String, CodingKey {
            case failure
            case status
            case systemMessage
            case testCaseScenarioId
            case testCaseScenarioType
        }
    }

    public struct TestResult: AWSDecodableShape {
        /// Show each group of test results.
        public let groups: [GroupResult]?

        public init(groups: [GroupResult]? = nil) {
            self.groups = groups
        }

        private enum CodingKeys: String, CodingKey {
            case groups
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring("tagKeys"))
        ]

        /// The resource ARN of an IoT Device Advisor resource. This can be SuiteDefinition ARN or SuiteRun ARN.
        public let resourceArn: String
        /// List of tag keys to remove from the IoT Device Advisor resource.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 20)
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateSuiteDefinitionRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "suiteDefinitionId", location: .uri("suiteDefinitionId"))
        ]

        /// Updates a Device Advisor test suite with suite definition configuration.
        public let suiteDefinitionConfiguration: SuiteDefinitionConfiguration
        /// Suite definition ID of the test suite to be updated.
        public let suiteDefinitionId: String

        public init(suiteDefinitionConfiguration: SuiteDefinitionConfiguration, suiteDefinitionId: String) {
            self.suiteDefinitionConfiguration = suiteDefinitionConfiguration
            self.suiteDefinitionId = suiteDefinitionId
        }

        public func validate(name: String) throws {
            try self.suiteDefinitionConfiguration.validate(name: "\(name).suiteDefinitionConfiguration")
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, max: 36)
            try self.validate(self.suiteDefinitionId, name: "suiteDefinitionId", parent: name, min: 12)
        }

        private enum CodingKeys: String, CodingKey {
            case suiteDefinitionConfiguration
        }
    }

    public struct UpdateSuiteDefinitionResponse: AWSDecodableShape {
        /// Timestamp of when the test suite was created.
        public let createdAt: Date?
        /// Timestamp of when the test suite was updated.
        public let lastUpdatedAt: Date?
        /// Amazon Resource Name (ARN) of the updated test suite.
        public let suiteDefinitionArn: String?
        /// Suite definition ID of the updated test suite.
        public let suiteDefinitionId: String?
        /// Updates the suite definition name. This is a required parameter.
        public let suiteDefinitionName: String?
        /// Suite definition version of the updated test suite.
        public let suiteDefinitionVersion: String?

        public init(createdAt: Date? = nil, lastUpdatedAt: Date? = nil, suiteDefinitionArn: String? = nil, suiteDefinitionId: String? = nil, suiteDefinitionName: String? = nil, suiteDefinitionVersion: String? = nil) {
            self.createdAt = createdAt
            self.lastUpdatedAt = lastUpdatedAt
            self.suiteDefinitionArn = suiteDefinitionArn
            self.suiteDefinitionId = suiteDefinitionId
            self.suiteDefinitionName = suiteDefinitionName
            self.suiteDefinitionVersion = suiteDefinitionVersion
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case lastUpdatedAt
            case suiteDefinitionArn
            case suiteDefinitionId
            case suiteDefinitionName
            case suiteDefinitionVersion
        }
    }
}

// MARK: - Errors

/// Error enum for IoTDeviceAdvisor
public struct IoTDeviceAdvisorErrorType: AWSErrorType {
    enum Code: String {
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize IoTDeviceAdvisor
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// Sends a Conflict Exception.
    public static var conflictException: Self { .init(.conflictException) }
    /// Sends an Internal Failure exception.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// Sends a Resource Not Found exception.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// Sends a validation exception.
    public static var validationException: Self { .init(.validationException) }
}

extension IoTDeviceAdvisorErrorType: Equatable {
    public static func == (lhs: IoTDeviceAdvisorErrorType, rhs: IoTDeviceAdvisorErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension IoTDeviceAdvisorErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
